home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Utilities / Winter Shell 1.0d2 / Source / Libraries / ScreenLib / ScreenLib.c next >
Encoding:
C/C++ Source or Header  |  1994-01-10  |  5.6 KB  |  205 lines  |  [TEXT/KAHL]

  1. /*    Functions for isolating the application from graphics devices, so that
  2.     the same code can be used on macs that support graphics devices as well
  3.     as macs that don't support them. Also, the common user interface tasks
  4.     of determining which screen to position a window on are handled quite
  5.     simply using this library. The function ScreenGet returns the library's
  6.     concept of the current screen and the function ScreenRect returns the
  7.     current screen's bounding rectangle, while ScreenGrayRect returns the
  8.     gray area (i.e., excluding the menu bar if on the main screen). To set
  9.     the current screen so that the next call to ScreenRect will return the
  10.     bounding rectangle of the screen containing the frontmost window simply
  11.     use
  12.         
  13.         ScreenSet(ScreenContainingWindow(window));
  14.     
  15.     Similarly, to ensure that the next window (e.g., alert) created will be on
  16.     the screen where the last mouse down occurred use
  17.     
  18.         ScreenSet(ScreenContainingPt(where));
  19.     
  20.     Since the window library uses the function ScreenGrayRect when positioning
  21.     windows at their default position and size these functions help ensure
  22.     compliance with the user interface guidlines for single and multiple 
  23.     screen macs.
  24.     
  25.     Portions based on the C/Shell application distributed on the System 7.0
  26.     Golden Release CD-ROM.
  27.  
  28.     Revisions:
  29.     
  30.     93/12/16 aih
  31.     - fixed bug if there was no current screen (defaults to main screen)
  32.     
  33.     93/12/05 aih
  34.     - fixed function for calculating screen region
  35.     - added function for calculating screen's gray rectangle
  36.     
  37.     93/03/19 AIH
  38.     - Changed ScreenLibBegin to ScreenInit
  39.     
  40.     91/07/02 AIH
  41.     - Added some assertions and comments
  42.     
  43.     91/05/12 Ari Halberstadt (AIH)
  44.     - Created this library. */
  45.  
  46. #include <stddef.h>
  47. #include "MacLib.h"
  48. #include "ScreenLib.h"
  49.  
  50. /* the current screen */
  51. static ScreenHandle gScreen;
  52.  
  53. /* true if the screen is a valid screen */
  54. Boolean ScreenValid(ScreenHandle screen)
  55. {
  56.     Boolean result = false;
  57.     
  58.     if (MacHasSingleScreen())
  59.         result = (screen == NULL);
  60.     else
  61.         result = (screen != NULL);
  62.     return(result);
  63. }
  64.  
  65. /* return the current screen */
  66. ScreenHandle ScreenGet(void)
  67. {
  68.     require(! gScreen || ScreenValid(gScreen));
  69.     return(gScreen ? gScreen : GetMainDevice());
  70. }
  71.  
  72. /* set the current screen, or do nothing if NULL */
  73. void ScreenSet(ScreenHandle screen)
  74. {
  75.     require(! screen || ScreenValid(screen));
  76.     if (screen)
  77.         gScreen = screen;
  78. }
  79.  
  80. /* Get region enclosing all of the screens. Needed since GetGrayRgn doesn't
  81.     include the menu bar. */
  82. const RgnHandle ScreenRgnAll(void)
  83. {
  84.     static RgnHandle screenRgn;
  85.     Rect gdRect = screenBits.bounds;
  86.     
  87.     if (! screenRgn) {
  88.         screenRgn = NewRgn();
  89.         FailNIL(screenRgn);
  90.         if (MacHasMultipleScreens())
  91.             gdRect = (**GetMainDevice()).gdRect;
  92.         RectRgn(screenRgn, &gdRect);
  93.         UnionRgn(screenRgn, GetGrayRgn(), screenRgn);
  94.     }
  95.     return(screenRgn);
  96. }
  97.  
  98. /* return the bounding rectangle of the current screen */
  99. void ScreenRect(Rect *r)
  100. {
  101.     *r = screenBits.bounds;
  102.     if (MacHasMultipleScreens())
  103.         *r = (**ScreenGet()).gdRect;
  104.     /* the rectangle must be at least the size of the original mac screen */
  105.     ensure(r->right - r->left >= 512 && r->bottom - r->top >= 342); 
  106. }
  107.  
  108. /* return bounding rectangle of screen's gray region */
  109. void ScreenGrayRect(Rect *gray)
  110. {
  111.     ScreenRect(gray);
  112.     if (ScreenHasMenuBar())
  113.         gray->top += GetMBarHeight();
  114. }
  115.  
  116. /* true if the current screen contains the menu bar */
  117. Boolean ScreenHasMenuBar(void)
  118. {
  119.     return(MacHasSingleScreen() || ScreenGet() == GetMainDevice());
  120. }
  121.  
  122. /* Return the screen containing the point. The point should be in global
  123.     coordinates. */
  124. ScreenHandle ScreenContainingPt(Point pt)
  125. {
  126.     GDHandle    gd; /* current device */
  127.     ScreenHandle screen = NULL; /* screen to return */
  128.     
  129.     if (MacHasMultipleScreens()) {
  130.         for (gd = GetDeviceList(); gd && ! screen; gd = GetNextDevice(gd)) {
  131.             if (TestDeviceAttribute(gd, screenDevice) &&
  132.                  TestDeviceAttribute(gd, screenActive) &&
  133.                  PtInRect(pt, &(**gd).gdRect))
  134.             {
  135.                 screen = gd;
  136.             }
  137.         }
  138.     }
  139.     return(screen);
  140. }
  141.  
  142. /* Return the screen containing the largest portion of the rectangle,
  143.     or NULL if the rectangle doesn't intersect any screen or the macintosh
  144.     doesn't support multiple screens. The rectangle should be in global
  145.     coordinates. */
  146. ScreenHandle ScreenContainingRect(Rect *r)
  147. {
  148.     Rect sect;            /* intersection of rectangle and device */
  149.     long area;            /* area of intersection */
  150.     long maxArea;        /* largest intersection found */
  151.     GDHandle    gd;        /* device being checked */
  152.     ScreenHandle screen = NULL;    /* screen to return */
  153.     
  154.     if (MacHasMultipleScreens()) {
  155.         maxArea = 0;
  156.         for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
  157.             if (TestDeviceAttribute(gd, screenDevice) &&
  158.                  TestDeviceAttribute(gd, screenActive) &&
  159.                  SectRect(r, &(**gd).gdRect, §))
  160.             {
  161.                 area = (sect.right - sect.left) * (sect.bottom - sect.top);
  162.                 if (area > maxArea) {
  163.                     screen = gd;
  164.                     maxArea = area;
  165.                 }
  166.             }
  167.         }
  168.     }
  169.     return(screen);
  170. }
  171.  
  172. /* Return the screen containing the largest portion of the window,
  173.     or NULL if either the window is invisible, or the macintosh
  174.     doesn't support multiple screens, or if the window is NULL.
  175.     This makes it simple to set the current screen:
  176.     
  177.         ScreenSet(ScreenContainingWindow(FrontWindow()))
  178.     
  179.     The current screen won't be changed if there is no front window. */
  180. ScreenHandle ScreenContainingWindow(WindowPtr window)
  181. {
  182.     GrafPtr port;
  183.     Rect portRect;
  184.     ScreenHandle screen = NULL;
  185.     
  186.     if (window) {
  187.         portRect = window->portRect;
  188.         GetPort(&port);
  189.         SetPort(window);
  190.         LocalToGlobal(&((Point *) &portRect)[0]);
  191.         LocalToGlobal(&((Point *) &portRect)[1]);
  192.         SetPort(port);
  193.         screen = ScreenContainingRect(&portRect);
  194.     }
  195.     return(screen);
  196. }
  197.  
  198. /* initialize the screen library */
  199. void ScreenInit(void)
  200. {
  201.     gScreen = NULL;
  202.     if (MacHasMultipleScreens())
  203.         gScreen = GetMainDevice();
  204. }
  205.